package com.cskaoyan.javase.object._2tostring;

/**
 * 方法的声明
 * Object类当中toString方法的，方法的声明很普通：
 *      public String toString()
 * 没有什么注意的地方，记住它有返回值，并且返回字符串String对象就可以了。
 *
 * 方法的作用:
 * 关于toString方法的作用，在JDK文档中，有详细的说明，主要说以下四点：
 *      1.返回该对象（调用toString方法的对象）的字符串表示。
 *      2.通常，toString方法会返回一个"以文本方式表示"此对象的字符串。
 *      3.结果应是一个简明但易于读懂的信息表达式。
 *      4.建议所有子类都重写此方法。
 *
 * Object类当中toString方法的默认实现:
 * 方法体如下:
 *      return getClass().getName() + "@" + Integer.toHexString(hashCode());
 * 解释:
 *      getClass().getName(): 是获取该类的全限定类名
 *      hashCode(): 返回该对象的哈希值,该方法的默认实现是通过计算对象的地址来获取哈希值
 *          也就是说,该方法返回的int整数可以近似看成,该对象地址值的十进制整数表示
 *      Integer.toHexString: 该方法将一个int整数变成十六进制字符串
 *      综上,该方法返回的是这样的一个字符串:
 *          "全限定类名 + @ + 十六进制地址值"
 *
 * toString方法实际上的用途:
 *      在java中,直接打印任何对象,或者它的引用(包括数组对象,和它的引用)
 *      都会自动调用类中的toString方法,所以打印引用,实际上打印的是它toString方法的返回值
 *      这是一个隐式的方法调用
 *      除此之外,直接用引用拼接字符串,也会自动调用toString方法,拼接返回值
 *
 *
 * toString方法的默认实现,打印地址值,在绝大多数情况下,意义不大
 * 所以文档建议我们重写该方法
 * 一般来说重写的原则都是打印属性的取值
 * 而且该方法建议用idea自动生成,不建议手写
 *
 *
 * 注意事项:
 *      1.如果类中有引用数据类型成员变量
 *          那就继续在方法中拼该引用数据类型成员变量的toString方法
 *          也就意味着需要重写该类的toString方法
 *      2.String这个引用数据类型并不需要再拼toString了
 *      3.toString方法在打印引用时,是一个隐式自动调用
 *          那么如果写出这个方法调用,合适吗?
 *          不合适,不要画蛇添足
 *      4.toString方法在开发中如果想要使用,那就直接自动生成
 *          不要在toString方法中写任何业务代码
 *          它的作用就是打印属性
 *      IDEA的debug模式下，会自动调用类的toString方法，去在界面上展示对象。
 *      如果你在toString方法中写赋值或者其它语句，就会导致debug模式运行下
 *      代码运行结果不正确，但正常run模式启动，结果正常的奇怪情况。
 *
 * @since 11:34
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*Student s = new Student(750, 18);
        System.out.println(s);
        System.out.println(s + "    hello world!");
        int[] arr = new int[3];
        // Implicit call to 'toString()' on array 'arr'
        System.out.println(arr);*/

        /*Student s = new Student(700, 18, new Star("蔡徐坤"));
        System.out.println(s);

        Student s2 = new Student(600, 18, null);
        System.out.println(s2);*/

        Star s = new Star("舞蹈区某up🐖");
        // System.out.println(s);
        System.out.println(s.name);
    }
}

class Star {
    String name;

    public Star(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        // name = "健身区某up🐖";
        return "Star{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Student {
    double score;
    int age;
    Star star;

    public Student(double score, int age) {
        this.score = score;
        this.age = age;
    }

    public Student(double score, int age, Star star) {
        this.score = score;
        this.age = age;
        this.star = star;
    }

    @Override
    public String toString() {
        return "Student{" +
                "score=" + score +
                ", age=" + age +
                ", star=" + star +
                '}';
    }
    /*@Override
    public String toString() {
        return "{Student age = " + age + ", score = " + score + "}";
    }*/

    /*@Override
    public String toString() {
        return "Student{" +
                "score=" + score +
                ", age=" + age +
                '}';
    }*/

    /*@Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Student{");
        sb.append("score=").append(score);
        sb.append(", age=").append(age);
        sb.append('}');
        return sb.toString();
    }*/
}
